package com.fan.gofast.util;

import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.nio.channels.FileChannel;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class FileHelper {

    /**
     * 文件改名字
     *
     * @param oldFile
     * @param newFile
     * @return
     * @throws IOException
     */
    public static boolean updateFileName(File oldFile, File newFile) throws IOException {
        if (!oldFile.isFile()) {
            return false;
        }
        if (newFile.isFile()) {
            newFile.delete();
        }
        return oldFile.renameTo(newFile);
    }

    /**
     * 复制一个文件(如果两个文件的路径一致，新的将会覆盖旧文件)
     *
     * @param oldFile 旧的文件路径
     * @throws IOException
     * @parm newFile 新的文件路径
     */
    public static boolean copyFile(File oldFile, File newFile) {
        FileChannel inputChannel = null;
        FileChannel outputChannel = null;
        try {
            inputChannel = new FileInputStream(oldFile).getChannel();
            outputChannel = new FileOutputStream(newFile).getChannel();
            outputChannel.transferFrom(inputChannel, 0, inputChannel.size());
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            try {
                if (inputChannel != null) {
                    inputChannel.close();
                }
                if (outputChannel != null) {
                    outputChannel.close();
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }

    }

    public static boolean downloadWebFile(String webFileUrl, String path, String userAgent, String referer) {
        InputStream in = null;
        OutputStream out = null;
        try {
            // 如果路径中含有中文,则进行转码操作
            Pattern pa = Pattern.compile("[\\u4e00-\\u9fa5]", Pattern.DOTALL);
            Matcher ma = pa.matcher(webFileUrl);
            String t;
            while (ma.find()) {
                t = ma.group();
                webFileUrl = webFileUrl.replace(t, URLEncoder.encode(t, "UTF-8"));
            }
            // 构造URL
            URL url = new URL(webFileUrl);

            // 打开连接
            URLConnection con = url.openConnection();
            if (userAgent != null) {
                con.setRequestProperty("User-Agent", userAgent); // 设
            }
            if (referer != null) {
                con.setRequestProperty("Referer", referer);
            }
            // 设置请求超时为5s
            con.setConnectTimeout(5 * 1000);
            // 输入流
            in = con.getInputStream();

            // 1K的数据缓冲
            byte[] bs = new byte[1024];
            // 读取到的数据长度
            int len;
            // 输出的文件流
            File sf = new File(path);
            File parentFile = new File(sf.getParent());
            if (!parentFile.exists()) {
                parentFile.mkdirs();
            }
            out = new FileOutputStream(path);
            // 开始读取
            while ((len = in.read(bs)) != -1) {
                out.write(bs, 0, len);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
                if (out != null) {
                    out.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * 下载网络图片到指定的目录
     *
     * @return
     */
    public static boolean downloadWebFile(String webFileUrl, String fileName, String parentPath, String userAgent, String referer) {
        return downloadWebFile(webFileUrl, parentPath + fileName, userAgent, referer);
    }

    /**
     * 功能：Java读取txt文件的内容 步骤： 1：先获得文件句柄 2：获得文件句柄当做是输入一个字节码流，需要对这个输入流进行读取
     * 3：读取到输入流后，需要读取生成字节流 4：一行一行的输出。readline()。 备注：需要考虑的是异常情况
     *
     * @param filePath
     */
    public static String readTxtFile(String filePath) {
        // 绝对路径或相对路径都可以，写入文件时演示相对路径,读取以上路径的input.txt文件
        //防止文件建立或读取失败，用catch捕捉错误并打印，也可以throw;
        //不关闭文件会导致资源的泄露，读写文件都同理
        //Java7的try-with-resources可以优雅关闭文件，异常时自动关闭文件；详细解读https://stackoverflow.com/a/12665271
        try (FileReader reader = new FileReader(filePath);
             BufferedReader br = new BufferedReader(reader) // 建立一个对象，它把文件内容转成计算机能读懂的语言
        ) {
            String line;
            //网友推荐更加简洁的写法
            StringBuffer sb = new StringBuffer("");
            while ((line = br.readLine()) != null) {
                // 一次读入一行数据
                sb.append(line + "\n");
            }
            return sb.toString();
        } catch (IOException e) {
            // e.printStackTrace();
            return null;
        }
    }

    /**
     * 文件写入操作
     */
    public static boolean writeFile(byte[] array, String target) {
        FileOutputStream out = null;
        try {
            out = new FileOutputStream(target);
            for (int i = 0; i < array.length; i++) {
                out.write(array[i]);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
        return false;
    }

    /**
     * 文本文件的写入操作
     *
     * @param path    文件路径
     * @param content 文件内容
     * @return
     */
    public static boolean writeTxtFile(String path, String content) {
        try {
            File writeName = new File(path); // 相对路径，如果没有则要建立一个新的output.txt文件
            writeName.createNewFile(); // 创建新文件,有同名的文件的话直接覆盖
            try (FileWriter writer = new FileWriter(writeName);
                 BufferedWriter out = new BufferedWriter(writer)
            ) {
                out.write(content); // \r\n即为换行
                out.flush(); // 把缓存区内容压入文件
                return true;
            }
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }

    }

    /**
     * 递归删除目录下所有子目录和文件
     */
    public static void deleteFile(File file) {
        try {
            File[] listFile = file.listFiles();
            for (File child : listFile) {
                if (child.isFile()) {
                    child.delete();
                } else if (child.isDirectory()) {
                    deleteChildDirAndFiles(child.listFiles());
                }
            }
            file.delete();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 递归删除目录下所有子目录和文件
     */
    public static void deleteChildDirAndFiles(File[] childFiles) {
        try {
            for (File file : childFiles) {
                if (file.exists()) {
                    if (file.isFile()) {
                        file.delete();
                    } else {
                        if (file.list().length > 0) {
                            deleteChildDirAndFiles(file.listFiles());
                            file.delete();
                        }
                    }
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * @throws
     * @Title: getAllFilePaths
     * @Description: 递归查询某个目录下所有的文件路径集合
     * @param: @param dir
     * @param: @param filePaths
     * @param: @return
     * @return: List<String>
     */
    public static List<String> getAllFilePaths(File dir, List<String> filePaths) {
        File[] files = dir.listFiles();
        if (files == null) {
            return filePaths;
        }
        for (File f : files) {
            if (f.isDirectory()) {
                filePaths.add(f.getPath());
                getAllFilePaths(f, filePaths);
            } else {
                filePaths.add(f.getPath());
            }
        }
        return filePaths;
    }


    /**
     * 读取 项目中某个文本文件(包括项目打包成的jar里面的)
     *
     * @param path(相对路径)
     * @return
     */
    public static String readResourceFile(String path) {
        if (path != null && path.indexOf("classpath") != -1) {
            path = path.replace("classpath", "").replace(":", "").replace("*", "");
        }
        StringBuffer stringBuffer = new StringBuffer();
        try (InputStream stream = FileHelper.class.getClassLoader().getResourceAsStream(path);
             BufferedReader br = new BufferedReader(new InputStreamReader(stream, "UTF-8"))
        ) {
            String line;
            while ((line = br.readLine()) != null) {
                stringBuffer.append(line);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return stringBuffer.toString();
    }


    public static void main(String[] args) {
//        String txt = FileHelper.readTxtFile("C:\\Users\\Ray\\Desktop/export_result (1).json");
//        List<Map> list = JSONHelper.convertToList(txt, Map.class);
//        String sb = new String("");
//        for (Map map : list) {
//            String sjbData = map.get("sjb_push_data").toString();
//            Map data = JSONHelper.convertToMap(sjbData);
//            if (data.get("loadPictureUrl") == null) {
//                continue;
//            }
//            //"voucher": "{\"loadPictureUrl\":\"https://storecdn.meiyibao.com/20191214/455c8527ae92423988863ed2da9ae59d.jpg\",\"signPictureUrl\":\"https://storecdn.meiyibao.com/20191214/455c8527ae92423988863ed2da9ae59d.jpg\"}",
//            Map temp = new HashMap();
//            temp.put("loadPictureUrl", data.get("loadPictureUrl"));
//            temp.put("signPictureUrl", data.get("unloadPictureUrl"));
//            sb += " update myb_waybill set voucher='" + JSONHelper.convertToJSON(temp) + "' where sjb_id='" + map.get("sjb_id").toString() + "';\n";
//        }
//        FileHelper.writeTxtFile("C:/Users/Ray/Desktop/a1.sql", sb);
    }
}
